import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { DragControls } from "three/addons/controls/DragControls.js";

import { indices, uvs, fwFaces, meshMode,colorDic } from "@/utils/three/attributes.js";
import calculator from "@/utils/three/calculator";
import { to2DArray } from "@/utils/common/common";
import { FontLoader } from "three/addons/loaders/FontLoader.js";
import { TextGeometry } from "three/addons/geometries/TextGeometry.js";

import {ViewHelper} from './viewHelper'

import { computeCadFloor, autoCadFloorTemplate } from "@/api/module2";

let sceneContainer,
  scene,
  camera,
  clock,
  renderer,
  planeMesh,
  gridHelper,
  wpWidth,
  wpHeight,
  orbitControls,
  dragControls,
  viewHelper;
let cubes = [];
let floorTexts = []; // 地板文本  
let fwMeshs = []; // 模板数组
let editmode = false;

let activeMesh = null; // 当前活动的构件
let activeFace = null; // 编辑的面
let isEditFW = false; // 是否正在编辑模板

let draged = false;

// 创建 Raycaster 和鼠标 Vector2
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();

let lastMousePosition = new THREE.Vector3(); // 记录鼠标按下时候的位置

var meshDragMarkers = []; //创建拖动的标志物
var meshDragGroup = new THREE.Group();
let curSelectedMess = ref(null); // 活动状态的模板实体

let drager = null;

// function animate() {
//   requestAnimationFrame(animate);
//   orbitControls.update();
//   renderer.render(scene, camera);
// }
export function initScene(anchor, refMesh) {
  curSelectedMess = refMesh;
  // 创建场景
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0x888888);

  sceneContainer = document.getElementById(anchor);

  wpWidth = sceneContainer.offsetWidth;
  wpHeight = sceneContainer.offsetHeight;

  clock = new THREE.Clock();

  // 创建相机
  camera = new THREE.PerspectiveCamera(90, wpWidth / wpHeight, 0.1, 1000000);
  // camera.position.x = -300;
  camera.position.y = -100000;
  camera.position.z += 4000;

  // 创建渲染器
  renderer = new THREE.WebGLRenderer({ antialias: true });
  // 渲染器能够渲染阴影效果
  renderer.shadowMap.enabled = true;
  renderer.setSize(wpWidth, wpHeight);
  sceneContainer.appendChild(renderer.domElement);

  // 创建一个平面作为底板
  const planeGeometry = new THREE.PlaneGeometry(500000, 500000);
  const planeMaterial = new THREE.MeshStandardMaterial({
    color: 0xffffffff,
    side: THREE.DoubleSide,
    transparent: true,
    opacity: 0,
  });
  planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
  planeMesh.rotation.z = 0.5 * Math.PI;
  planeMesh.position.set(0, 0, 0);
  planeMesh.userData = {
    type: "plane",
  };
  scene.add(planeMesh);

  // 添加网格辅助器
  gridHelper = new THREE.GridHelper(500000, 200); // 创建一个200单位的网格，细分为50个方格
  gridHelper.rotation.x = 0.5 * Math.PI;
  gridHelper.material.color.setHex(0x999999);
  //gridHelper.position.y = -150;
  scene.add(gridHelper);

  // 方向光
  const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
  directionalLight.position.set(10, 10, 10);

  directionalLight.shadow.mapSize.width = 1024; // default
  directionalLight.shadow.mapSize.height = 1024; // default
  directionalLight.shadow.camera.near = 0.05; // default
  directionalLight.shadow.camera.far = 500; // default
  //将范围调大
  directionalLight.shadow.camera.top = 20; /// 这个是生效的属性
  directionalLight.shadow.camera.right = 20;
  directionalLight.shadow.camera.left = -20;
  directionalLight.shadow.camera.bottom = -20;
  directionalLight.castShadow = true;
  scene.add(directionalLight);

  // 环境光
  const ambientLight = new THREE.AmbientLight(0xffffff, 2);
  scene.add(ambientLight);

  // 添加鼠标控制
  orbitControls = new OrbitControls(camera, renderer.domElement);
  // controls.enableDamping = true; // 使得相机移动更加平滑
  orbitControls.dampingFactor = 0.05; // 阻尼效果

  // window.addEventListener('mouseup', onPointerUp);
  // window.addEventListener('resize', onWindowResize, false);

  // window.addEventListener('mousemove', onMouseMove, false);

  // // 添加鼠标双击事件，用于将物体还原到初始位置
  // window.addEventListener('dblclick', restoreObject);

  // window.addEventListener('contextmenu', (event) => {
  //     editmode && event.preventDefault()
  // });
  addDragControl();
  addViewHelper();
  createDragMarkers(scene, meshDragMarkers);
  // animate()
  return {
    scene,
    camera,
    renderer,
    container: sceneContainer,
    orbitControls,
    dragControls,
    planeMesh,
    wpWidth,
    wpHeight,
    raycaster,
    mouse,
  };
}

export const resetScene = () => {
  let length = scene.children.length
  for (let index = length-1; index > 0; index--) {
    const element = scene.children[index];
    if(element.userData.type){  // 添加的构件
      scene.remove(element);
    }
  }
}

export const drawCube = (vectors, type, oriData) => {
  // const facevertices = getCubeFaces(vectors);
  let mesh;
  if ("@YS-楼面" == type) {
    // var loader = new FontLoader();
    // loader.load("/src/assets/optimer_bold.typeface.json", (res) => {
    //   let textGeometry = new TextGeometry(oriData.entityText, {
    //     font: res, // 字体格式
    //     size: 300, // 字体大小
    //     depth: 50, // 字体深度
    //     curveSegments: 11, // 曲线控制点数
    //     bevelEnabled: true, // 斜角
    //     bevelThickness: 0.1, // 斜角的深度
    //     bevelSize: 1, // 斜角的大小
    //     bevelSegments: 1, // 斜角段数
    //   });
    //   var mat = new THREE.MeshPhongMaterial({
    //     color: "white",
    //     opacity: 0.8,
    //     shininess: 1,
    //   });
    //   mesh = new THREE.Mesh(textGeometry, mat);
    //   let point = vectors[3];
    //   mesh.position.copy(new THREE.Vector3(point[0], point[1], point[2]));
    //   mesh.userData = {
    //     type: "floorText",
    //     oriData,
    //   };
    //   scene.add(mesh);
    //   floorTexts.push(mesh);
    // });
  } else {
    let { newvectors, idx } = calculator.calcIndices(vectors);
    const facevertices = newvectors.flat();
    var geometry = new THREE.BufferGeometry();
    geometry.setAttribute(
      "position",
      new THREE.BufferAttribute(new Float32Array(facevertices), 3)
    );

    // console.log(facevertices,idx)
    geometry.setIndex(idx);
    // geometry.setAttribute("uv", new THREE.BufferAttribute(uvs, 2));
    geometry.computeVertexNormals();
    let material = new THREE.MeshPhysicalMaterial({
      color: colorDic[type],
      flatShading: true,
      side: THREE.DoubleSide,
      // wireframe: true  //是否以线框模式渲染物体
    });
    mesh = new THREE.Mesh(geometry, material);
    if(meshMode.find(e => e.name == type)){
      type = "formwork"
    }
    mesh.userData = {
      type,
      ...oriData,
    };
    scene.add(mesh);
    cubes.push(mesh);
  }
};

export const regDrop = () => {
  renderer.domElement.addEventListener("dragover", (event) => {
    // 阻止默认行为以允许放置
    event.preventDefault();
  });

  // 元素放到场景中
  renderer.domElement.addEventListener("drop", (event) => {
    // event.preventDefault();
    let fwData = event.dataTransfer.getData("text");
    fwData = JSON.parse(fwData);

    mouse.x = ((event.clientX - 208) / wpWidth) * 2 - 1;
    mouse.y = -((event.clientY - 98) / wpHeight) * 2 + 1;

    // 更新射线
    raycaster.setFromCamera(mouse, camera);

    // 计算与平面的交点
    const intersects = raycaster.intersectObject(planeMesh);
    if (intersects.length > 0) {
      const intersection = intersects[0];
      const centerpoint = intersection.point;
      const centerX = Math.round(centerpoint.x),
        centerY = Math.round(centerpoint.y);
      // 先写个默认的2000*1000
      const size = { w: 2000, h: 1000 };

      const vertices = calculator.calcFWvers(size, centerX, centerY);
      if (fwData.name == "顶固") {
        const radius = 100;
        const height = 3000;
        const cylinderGeometry = new THREE.CylinderGeometry(
          radius,
          radius,
          height,
          32
        );
        const cylinderMaterial = new THREE.MeshBasicMaterial({
          color: 0x00ff00,
        });
        const cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial);

        // 立方体参数：边长40cm，高度10cm
        const cubeSize = 500;
        const cubeHeight = 200;
        const cubeGeometry = new THREE.BoxGeometry(
          cubeSize,
          cubeHeight,
          cubeSize
        );
        const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

        // 将立方体放置在圆柱顶端，调整位置，使其居中
        cube.position.y = height / 2 + cubeHeight / 2; // 放置在圆柱顶端

        // 创建一个整体的Group对象
        const group = new THREE.Group();
        group.add(cylinder);
        group.add(cube);

        group.position.copy(new THREE.Vector3(centerX, centerY, 0))
        group.rotation.x = 0.5 * Math.PI
        group.position.z = 1500
        
        scene.add(group);
        fwMeshs.push(group);
        dragControls.objects.push(group);
      } else {
        const formWorkGeo = new THREE.BufferGeometry();
        formWorkGeo.setAttribute(
          "position",
          new THREE.BufferAttribute(new Float32Array(vertices), 3)
        );
        formWorkGeo.setIndex(indices);
        formWorkGeo.setAttribute("uv", new THREE.BufferAttribute(uvs, 2));
        formWorkGeo.computeVertexNormals();
        const mesh = new THREE.Mesh(
          formWorkGeo,
          new THREE.MeshStandardMaterial({
            color: 0xff00ff,
            side: THREE.DoubleSide,
            transparent: true,
            opacity: 1,
          })
        );
        mesh.userData = {
          type: "formwork",
          info: fwData,
        };
        scene.add(mesh);
        fwMeshs.push(mesh);
        dragControls.objects.push(mesh);
      }
    }
  });
};

// 鼠标悬停
export const regHover = () => {
  const onMouseMove = (event) => {
    // 将鼠标位置归一化到 -1 到 1 之间（适用于 Three.js）
    mouse.x = ((event.clientX - 208) / wpWidth) * 2 - 1;
    mouse.y = -((event.clientY - 98) / wpHeight) * 2 + 1;

    // 通过 Raycaster 投射一条射线
    raycaster.setFromCamera(mouse, camera);

    // 检查与哪些对象相交
    const intersects = raycaster.intersectObjects(scene.children);

    cubes.forEach((cube) => {
      let type = cube.userData.type;
      let material = cube.material;
      // 经过计算的墙体会有多个材质，取第一个
      if (cube.material instanceof Array) {
        material = cube.material[0];
      }
      try {
        material.color.set(colorDic[type]); // 先将所有物体颜色重置原始色
      } catch (e) {
        console.error(e);
      }
    });

    // 如果射线与对象相交，改变对象的颜色
    if (intersects.length > 0) {
      const element = intersects[0];
      const userData = element.object.userData;
      if (userData.type) {
        let type = userData.type;
        let material = element.object.material;
        if (material instanceof Array) {
          material = element.object.material[0];
        }
        material.color.set(colorDic[`${type}hl`]); //
      } else {
      }
    } else {
    }
  };

  // 监听鼠标移动事件
  window.addEventListener("mousemove", onMouseMove, false);
};

//  点击选择元素
export const regClick = () => {
  const onClick = (event) => {
    if (draged) return;
    mouse.x = ((event.clientX - 208) / wpWidth) * 2 - 1;
    mouse.y = -((event.clientY - 98) / wpHeight) * 2 + 1;

    raycaster.setFromCamera(mouse, camera);

    const intersects = raycaster.intersectObjects(scene.children);
    if (intersects.length > 0) {
      const intersect = intersects[0];
      const userData = intersect.object.userData;
      if (userData.type == "formwork") {
        activeMesh = intersect;
        const positionArray =
          intersect.object.geometry.attributes.position.array;
        let arr = Array.from(positionArray);
        const faceArr = to2DArray(to2DArray(arr, 3), 4);

        const points = calculator.calcFaceCenter(faceArr);
        createHotPoint(points);
      } else {
        removeHP();
        if (userData.type == "floorText") {
          console.log(userData.oriData);
        }
      }
    }
  };
  const onSceneMouseUp = (event) => {
    event.preventDefault();
    drager.release();
    sceneMouseClick(event);
  };
  const onSceneMouseDown = (event) => {
    if (curSelectedMess.value != null) {
      drager.callDrag(curSelectedMess.value, event, adjustMessVertexsByFace);
    }
  };
  // 监听鼠标事件
  sceneContainer.addEventListener("mouseup", onSceneMouseUp, false);
  sceneContainer.addEventListener("mousedown", onSceneMouseDown, false);
};

// 拖动改变模板大小
// export const regDrag = () => {
//   const onMouseDown = (event) => {
//     draged = false;
//     mouse.x = ((event.clientX - 208) / wpWidth) * 2 - 1;
//     mouse.y = -((event.clientY - 98) / wpHeight) * 2 + 1;
//     raycaster.setFromCamera(mouse, camera);
//     const intersects = raycaster.intersectObjects(scene.children);
//     if (intersects.length > 0) {
//       const hotointMesh = intersects.find(
//         (intersect) => intersect.object.userData.type == "hotPiont"
//       );
//       if (hotointMesh) {
//         //选中热点
//         orbitControls.enabled = false;
//         isEditFW = true;
//         activeFace = hotointMesh.object.userData.face;
//       }
//     }

//     const plane = raycaster.intersectObject(planeMesh);
//     if (plane.length > 0) {
//       lastMousePosition = plane[0].point;
//     }
//   };

//   const onMouseMove = (event) => {
//     if (isEditFW) {
//       // 鼠标选取热点拖拽
//       draged = true;
//       // console.log(activeMesh, activeFace)
//       mouse.x = ((event.clientX - 208) / wpWidth) * 2 - 1;
//       mouse.y = -((event.clientY - 98) / wpHeight) * 2 + 1;

//       // 更新射线投射器
//       raycaster.setFromCamera(mouse, camera);

//       const intersects = raycaster.intersectObject(planeMesh);

//       if (intersects.length > 0) {
//         // 获取交点的世界坐标
//         const currentMousePosition = intersects[0].point;

//         // 计算移动距离
//         const disX = currentMousePosition.x - lastMousePosition.x;
//         const disY = currentMousePosition.y - lastMousePosition.y;
//         const disZ = currentMousePosition.z - lastMousePosition.z;

//         // console.log('x:'+disX, 'y:'+disY,'z:'+disZ);

//         let distance = 0;
//         switch (activeFace) {
//           case 0:
//           case 1:
//             distance = disZ;
//             break;
//           case 2:
//           case 3:
//             distance = disY;
//             break;
//           case 4:
//           case 5:
//             distance = disX;
//             break;
//         }

//         if (Math.abs(distance) >= 50) {
//           distance = distance < 0 ? -100 : 100;
//           let geometry = activeMesh.object.geometry;
//           let positions = geometry.getAttribute("position");

//           let arr = Array.from(positions.array);
//           const faceArr = to2DArray(to2DArray(arr, 3), 4);

//           let newvectors = calculator.calcNewPositions(
//             activeFace,
//             faceArr,
//             distance
//           );

//           newvectors = newvectors.flat(Infinity);

//           geometry.setAttribute(
//             "position",
//             new THREE.BufferAttribute(new Float32Array(newvectors), 3)
//           );
//           geometry.getAttribute("position").needsUpdate = true;
//           geometry.computeBoundingBox();
//           activeMesh.object.updateMatrixWorld();

//           positions.needsUpdate = true;
//           lastMousePosition.copy(currentMousePosition); // 更新点，重新计算距离
//         }

//         // positions.needsUpdate = true;
//       }
//     }

//     // event.preventDefault()
//     // event.stopPropagation()
//   };

//   const onMouseUp = (event) => {
//     orbitControls.enabled = true;
//     isEditFW = false;
//     event.preventDefault();
//     event.stopPropagation();
//   };

//   window.addEventListener("mousedown", onMouseDown, false);
//   window.addEventListener("mouseup", onMouseUp, false);
//   window.addEventListener("mousemove", onMouseMove, false);
// };

const addViewHelper = () => {
  viewHelper = new ViewHelper(camera,sceneContainer)
  renderer.autoClear = false
}

export const addDragControl = () => {
  dragControls = new DragControls(fwMeshs, camera, renderer.domElement);
  dragControls.mouseButtons = {
    LEFT: THREE.MOUSE.RIGHT,
    MIDDLE: null,
    RIGHT: null,
  };

  // 监听 drag 事件，限制物体只能在 XY 平面上移动
  dragControls.addEventListener("drag", function (event) {
    event.object.position.z = 0; // 将 Z 坐标固定为 0，确保只在 XY 平面移动
  });

  // 禁用 OrbitControls 在拖动过程中
  dragControls.addEventListener("dragstart", function () {
    if (null == orbitControls || typeof orbitControls == "undefined") {
      return;
    }
    orbitControls.enabled = false; // 禁用 OrbitControls
  });

  // 重新启用 OrbitControls 在拖动结束后
  dragControls.addEventListener("dragend", function () {
    if (null == orbitControls || typeof orbitControls == "undefined") {
      return;
    }
    orbitControls.enabled = true; // 启用 OrbitControls
  });
};

function removeHP() {
  meshDragGroup.visible = false;
  // activeMesh = null;
  // const allObj = scene.children;
  // const hotpoint = allObj.filter((e) => e.userData.type == "hotPiont");
  // hotpoint.forEach((mesh) => {
  //   scene.remove(mesh);
  // });
}

function createHotPoint(points) {
  points.forEach((point, index) => {
    const geometry = new THREE.BoxGeometry(20, 20, 20);
    const material = new THREE.MeshBasicMaterial({ color: 0xffffff });
    const cube = new THREE.Mesh(geometry, material);
    cube.userData = { type: "hotPiont", face: index };
    cube.position.set(point[0], point[1], point[2]);
    scene.add(cube);
  });
}

function createDragMarkers(hScene, dragMarkers) {
  if (null == dragMarkers || dragMarkers.length > 0) {
    return dragMarkers;
  }
  var dragMarker;
  for (let i = 0; i < 6; i++) {
    var opt = {};
    opt.faceindex = i;
    opt.type = "dragmarker";
    dragMarker = createDragMarker(hScene, opt);
    if (null == dragMarker) {
      continue;
    }
    dragMarkers.push(dragMarker);
    meshDragGroup.add(dragMarker);
    hScene.add(meshDragGroup);
  }
  return dragMarkers;
}

const setCamPosi = (minX, minY, maxX, maxY) => {
  let centerX = (minX + maxX) / 2;
  let centerY = (minY + maxY) / 2;
  // console.log(centerX,centerY)
  camera.position.set(centerX, centerY, 8800);
  orbitControls.target.set(centerX, centerY, 0);

  orbitControls.update();
};

export const setDrager = (ins) => {
  drager = ins;
};

// 渲染场景
const render = () => {
  orbitControls.update(); // 更新 OrbitControls
  const delta = clock.getDelta();
  renderer.render(scene, camera);
  viewHelper.render( renderer )
  if (viewHelper.animating) {
    viewHelper.update(delta)
  }
  requestAnimationFrame(render); // 渲染循环
};

function sceneMouseClick(event) {
  if (event.target.id == "panel") {
    return;
  }
  curSelectedMess.value = null;
  //完成模型选择
  mouse.x = ((event.clientX - 208) / wpWidth) * 2 - 1;
  mouse.y = -((event.clientY - 98) / wpHeight) * 2 + 1;
  raycaster.setFromCamera(mouse, camera);
  // 计算物体和射线的焦点
  var intersects = raycaster.intersectObjects(scene.children);
  if (null == intersects || intersects.length < 1) {
    return;
  }
  var iSize = intersects.length;
  var intersect;

  let tempAr = []
  if (iSize > 0) {
    intersect = intersects[0];
    var userData = intersect.object.userData;
    console.log(userData.entityId);
    if (userData.type == "formwork") {
      curSelectedMess.value = intersect;
      setMessMarkers(curSelectedMess.value);
    } else {
      event.button == 0 && removeHP();
      if (userData.type == "floorText") {
        console.log(userData.oriData);
        let data = {
          entityId: userData.oriData.entityId,
        };
        computeCadFloor(data).then((res) => {
          let element = res.data[0];
          element.entityId = data.entityId
          element.oripoints = JSON.parse(JSON.stringify(element.points))
          element.vectors = calculator.pointsFrom4To8(
            "@YS-楼面",
            element.points,
            38000,
            110
          );
          drawCube(element.vectors, element.entityName, element);
          for (let index = 1; index <  res.data.length; index++) {
            const fwelement =  res.data[index];
            fwelement.oripoints = JSON.parse(JSON.stringify(fwelement.points))
            fwelement.vectors = calculator.pointsFrom4To8(
              fwelement.entityTypeName,
              fwelement.points,
              38000,
              110
            );
            fwelement.vectors && drawCube(fwelement.vectors, fwelement.entityTypeName, fwelement);
            fwelement.entityTypeName == '底笼' && tempAr.push(fwelement)
          }
          // console.log(tempAr)
        });
      } else if (userData.type == "计算楼面"){
        let fwattrs = userData.fwattrs
        for (let index = 1; index <  fwattrs.length; index++) {
          const fwelement = fwattrs[index];
          fwelement.oripoints = JSON.parse(JSON.stringify(fwelement.points))
          fwelement.vectors = calculator.pointsFrom4To8(
            fwelement.entityTypeName,
            fwelement.points,
            38000,
            110
          );
          fwelement.vectors && drawCube(fwelement.vectors, fwelement.entityTypeName, fwelement);
          fwelement.entityTypeName == '底笼' && tempAr.push(fwelement)
        }
      }else{
        if(userData.oripoints){
          let floorpoints = userData.oripoints.map(e => {
            let {x,y} = e
            return {
              x,y
            }
          })
          let data = {
            entityId: userData.entityId,
            points: floorpoints
          };
          // autoCadFloorTemplate(data).then(res => {
          //   console.log(res)
          // })
        }
      }

      // var loader = new FontLoader();
      // userData.entityId &&
      //   loader.load("/src/assets/optimer_bold.typeface.json", (res) => {
      //     let textGeometry = new TextGeometry(userData.entityId, {
      //       font: res, // 字体格式
      //       size: 200, // 字体大小
      //       depth: 5, // 字体深度
      //       curveSegments: 11, // 曲线控制点数
      //       bevelEnabled: true, // 斜角
      //       bevelThickness: 0.1, // 斜角的深度
      //       bevelSize: 1, // 斜角的大小
      //       bevelSegments: 1, // 斜角段数
      //     });
      //     var mat = new THREE.MeshPhongMaterial({
      //       color: "red",
      //       opacity: 0.8,
      //       shininess: 1,
      //     });
      //     var mesh = new THREE.Mesh(textGeometry, mat);
      //     let point = intersect.point;
      //     point.z += 200;
      //     mesh.position.copy(point);
      //     mesh.userData = {
      //       type: "text",
      //     };
      //     scene.add(mesh);
      //   });
    }
  }
  // togglePanel()
}
export function getCurSelectedMess() {
  return curSelectedMess.value;
}
function setMessMarkers(hMess) {
  if (null == hMess || typeof hMess == "undefined") {
    return;
  }
  var messType = getMessType(hMess);
  if ("SphereGeometry" == messType) {
    return;
  }
  var points = getMessPoints(hMess);
  var facePoints;
  var centerPoint;
  var messCenterPoint = getCenterPoint(points);
  var curPostion = hMess.point;

  if (null != meshDragGroup.children) {
    var iChild = meshDragGroup.children.length;
    var hChild;
    for (var i = iChild - 1; i >= 0; i--) {
      hChild = meshDragGroup.children[i];
      if (null == hChild || null == hChild.geometry) {
        continue;
      }
      if ("SphereGeometry" != hChild.geometry.type) {
        meshDragGroup.remove(hChild);
        continue;
      }
    }
  }
  meshDragGroup.visible = true;
  hMess.object.add(meshDragGroup);
  //取得各个面以及面的中心点
  updateMessMarkerPoints(hMess);
}

function updateMessMarkerPoints(hMess) {
  if (null == hMess || typeof hMess == "undefined") {
    return;
  }
  var points = getMessPoints(hMess);
  //取得各个面以及面的中心点
  for (var faceIdx = 0; faceIdx < 6; faceIdx++) {
    var facePoints = getMessFacePoints(hMess, faceIdx, points);
    var centerPoint = getCenterPoint(facePoints);
    setMarkerPoint(meshDragMarkers, faceIdx, centerPoint);
  }
}

//设置标记物的位置
function setMarkerPoint(hMarkers, iIdx, point) {
  if (
    null == hMarkers ||
    typeof hMarkers == "undefined" ||
    !(hMarkers instanceof Array)
  ) {
    return;
  }
  if (null == point || typeof point == "undefined") {
    return;
  }
  if (null == iIdx || typeof iIdx != "number") {
    return;
  }
  var iSize = hMarkers.length;
  if (iIdx < 0 || iIdx >= iSize) {
    return;
  }

  var hMarker = hMarkers[iIdx];
  // 设置物体的位置
  hMarker.position.set(point.x, point.y, point.z);
  hMarker.visible = true;
}

function getCubeFaces(vertices) {
  // 每个面的顶点（顺时针或逆时针）
  const faces = [
    // 底面
    [0, 1, 2, 3],
    // 顶面
    [4, 5, 6, 7],
    // 前面
    [0, 1, 5, 4],
    // 后面
    [2, 3, 7, 6],
    // 左面
    [0, 3, 7, 4],
    // 右面
    [1, 2, 6, 5],
  ];
  // 生成顶点数组
  const facesVertices = [];
  faces.forEach((face) => {
    face.forEach((index) => {
      facesVertices.push(...vertices[index]);
    });
  });

  return facesVertices;
}

//取得模型的类别
function getMessType(hMess) {
  var hGeometry = getMessGeometry(hMess);
  if (null == hGeometry || typeof hGeometry == "undefined") {
    return null;
  }
  return hGeometry.type;
}

//取得模型的类别
function getMessGeometry(hMess) {
  if (null == hMess || typeof hMess == "undefined") {
    return null;
  }
  var hGeometry = null;
  try {
    hGeometry = hMess.geometry;
  } catch (ex) {
    hGeometry = null;
  }
  if (null == hGeometry || typeof hGeometry == "undefined") {
    if (null == hMess.object || typeof hMess.object == "undefined") {
      return null;
    }
    try {
      hGeometry = hMess.object.geometry;
    } catch (ex) {
      hGeometry = null;
    }
  }
  return hGeometry;
}

//取得顶点中心点
function getCenterPoint(points) {
  if (null == points || !(points instanceof Array)) {
    return null;
  }
  var iSize = points.length;
  var point;
  var iSum = 0;
  var xSum = 0;
  var ySum = 0;
  var zSum = 0;
  for (var iIdx = 0; iIdx < iSize; iIdx++) {
    point = points[iIdx];
    if (null == point) {
      continue;
    }
    iSum++;
    xSum = accAdd(xSum, point.x);
    ySum = accAdd(ySum, point.y);
    zSum = accAdd(zSum, point.z);
  }
  if (iSum < 1) {
    return null;
  }
  xSum = accDiv(xSum, iSum);
  ySum = accDiv(ySum, iSum);
  zSum = accDiv(zSum, iSum);
  return { x: xSum, y: ySum, z: zSum };
}
//取得模型[hMess]指定面[faceIdx]的点 , points可以回传模型的所有顶点  底面[0, 1, 2, 3] 顶面 [4, 5, 6, 7]
function getMessFacePoints(hMess, faceIdx, points) {
  if (null == hMess || typeof hMess == "undefined") {
    return;
  }
  if (
    null == faceIdx ||
    typeof faceIdx != "number" ||
    faceIdx < 0 ||
    faceIdx >= 6
  ) {
    faceIdx = 0;
  }
  if (null == points || !(points instanceof Array) || points.length < 1) {
    points = getMessPoints(hMess);
  }
  if (null == points || !(points instanceof Array) || points.length < 8) {
    return null;
  }
  const faces = [
    [0, 1, 2, 3], // 底面
    [4, 5, 6, 7], // 顶面
    [0, 1, 5, 4], // 前面
    [2, 3, 7, 6], // 后面
    [0, 3, 7, 4], // 左面
    [1, 2, 6, 5], // 右面
  ];
  var idxs = faces[faceIdx];
  var result = [];
  var point;
  idxs.forEach((idx) => {
    point = points[idx];
    result.push(point);
  });
  return result;
}

//取得模型指定面的点
function getMessVertexs(hMess) {
  if (null == hMess || typeof hMess == "undefined") {
    return null;
  }
  if (null == hMess.object || typeof hMess.object == "undefined") {
    return null;
  }
  if (
    null == hMess.object.geometry ||
    typeof hMess.object.geometry == "undefined"
  ) {
    return null;
  }
  if (
    null == hMess.object.geometry ||
    typeof hMess.object.geometry == "undefined"
  ) {
    return null;
  }
  if (
    null == hMess.object.geometry.attributes ||
    typeof hMess.object.geometry.attributes == "undefined"
  ) {
    return null;
  }
  if (
    null == hMess.object.geometry.attributes.position ||
    typeof hMess.object.geometry.attributes.position == "undefined"
  ) {
    return null;
  }
  return hMess.object.geometry.attributes.position.array;
}
//取得模型指定面的点
function getMessPoints(hMess) {
  var vertexs = getMessVertexs(hMess);
  if (null == vertexs || !(vertexs instanceof Float32Array)) {
    return null;
  }
  var point;
  var result = [];
  for (var i = 0; i < 8; i++) {
    point = vertexToPoint(vertexs, i);
    if (null == point) {
      continue;
    }
    result.push(point);
  }
  return result;
}
//取得三维中的Vertice坐标转变为点坐标
function vertexToPoint(vertexs, pointIdx) {
  if (null == pointIdx || typeof pointIdx != "number") {
    return null;
  }
  if (
    null == vertexs ||
    typeof vertexs == "undefined" ||
    !(vertexs instanceof Float32Array)
  ) {
    return null;
  }
  var xIdx = pointIdx * 3;
  var yIdx = xIdx + 1;
  var zIdx = xIdx + 2;
  var iSize = vertexs.length;
  if (zIdx >= iSize || zIdx < 2) {
    return null;
  }
  var x = vertexs[xIdx];
  var y = vertexs[yIdx];
  var z = vertexs[zIdx];
  return { x: x, y: y, z: z };
}

//创建拖动的标志物
function createDragMarker(hScene, opt) {
  if (null == opt || typeof opt == "undefined") {
    opt = {};
  }
  const geometry = new THREE.SphereGeometry(150, 32, 16);
  const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
  var dragMarker = new THREE.Mesh(geometry, material);
  dragMarker.visible = false;
  dragMarker.userData = opt;
  hScene.add(dragMarker);
  return dragMarker;
}

// 两个浮点数求和
function accAdd(num1, num2) {
  var r1, r2, m;
  try {
    r1 = num1.toString().split(".")[1].length;
  } catch (e) {
    r1 = 0;
  }
  try {
    r2 = num2.toString().split(".")[1].length;
  } catch (e) {
    r2 = 0;
  }
  m = Math.pow(10, Math.max(r1, r2));
  // return (num1*m+num2*m)/m;
  return Math.round(num1 * m + num2 * m) / m;
}
// 两个浮点数相减
function accSub(num1, num2) {
  var r1, r2, m;
  try {
    r1 = num1.toString().split(".")[1].length;
  } catch (e) {
    r1 = 0;
  }
  try {
    r2 = num2.toString().split(".")[1].length;
  } catch (e) {
    r2 = 0;
  }
  m = Math.pow(10, Math.max(r1, r2));
  n = r1 >= r2 ? r1 : r2;
  return (Math.round(num1 * m - num2 * m) / m).toFixed(n);
}
// 两数相乘
function accMul(num1, num2) {
  var m = 0,
    s1 = num1.toString(),
    s2 = num2.toString();
  try {
    m += s1.split(".")[1].length;
  } catch (e) {}
  try {
    m += s2.split(".")[1].length;
  } catch (e) {}
  return (
    (Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) /
    Math.pow(10, m)
  );
}
// 两数相除
function accDiv(num1, num2) {
  var t1, t2, r1, r2;
  try {
    t1 = num1.toString().split(".")[1].length;
  } catch (e) {
    t1 = 0;
  }
  try {
    t2 = num2.toString().split(".")[1].length;
  } catch (e) {
    t2 = 0;
  }
  r1 = Number(num1.toString().replace(".", ""));
  r2 = Number(num2.toString().replace(".", ""));
  return (r1 / r2) * Math.pow(10, t2 - t1);
}

function adjustMessVertexsByFace(hMess, faceIdx, opt) {
  if (null == hMess || typeof hMess == "undefined") {
    return null;
  }
  if (null == opt || typeof opt == "undefined") {
    return null;
  }
  if (
    null == faceIdx ||
    typeof faceIdx != "number" ||
    faceIdx < 0 ||
    faceIdx > 5
  ) {
    return;
  }
  var hGeometry = getMessGeometry(hMess);
  if (null == hGeometry || typeof hGeometry == "undefined") {
    return null;
  }
  const faces = [
    [0, 1, 2, 3], // 底面
    [4, 5, 6, 7], // 顶面
    [0, 1, 5, 4], // 前面
    [2, 3, 7, 6], // 后面
    [0, 3, 7, 4], // 左面
    [1, 2, 6, 5], // 右面
  ];
  var iIdxs = faces[faceIdx];
  var iSize = iIdxs.length;
  var iIdx;
  for (var i = 0; i < iSize; i++) {
    iIdx = iIdxs[i];
    adjustMessVertexsByPoint(hMess, iIdx, opt);
  }
  hGeometry.verticesNeedUpdate = true;
  hGeometry.getAttribute("position").needsUpdate = true;
  hGeometry.computeBoundingBox();
  //取得各个面以及面的中心点
  updateMessMarkerPoints(hMess);
}
function adjustMessVertexsByPoint(hMess, iIdx, opt) {
  if (null == hMess || typeof hMess == "undefined") {
    return null;
  }
  if (null == opt || typeof opt == "undefined") {
    return null;
  }
  if (null == iIdx || typeof iIdx != "number" || iIdx < 0 || iIdx > 7) {
    return;
  }
  var hGeometry = getMessGeometry(hMess);
  if (null == hGeometry || typeof hGeometry == "undefined") {
    return null;
  }
  if (
    null == hGeometry.attributes ||
    typeof hGeometry.attributes == "undefined"
  ) {
    return null;
  }
  if (
    null == hGeometry.attributes.position ||
    typeof hGeometry.attributes.position == "undefined"
  ) {
    return null;
  }
  var x = opt.x;
  var y = opt.y;
  var z = opt.z;

  if (null == x || typeof x != "number") {
    x = null;
  }
  if (null == y || typeof y != "number") {
    y = null;
  }
  if (null == z || typeof z != "number") {
    z = null;
  }
  // 0              1             2            3             4         5
  // 底面          顶面           前面         后面          左面       右面
  // 0  1  2  3    4  5  6  7   8  9  10 11 12  13 14 15 16  17 18 19 20  21 22 23
  //[0, 1, 2, 3], [4, 5, 6, 7],[0, 1, 5, 4],[2, 3, 7, 6],[0, 3, 7, 4],[1, 2, 6, 5]
  //            0         1        2        3          4         5         6        7
  var pArr = [
    [0, 8, 16],
    [1, 9, 20],
    [2, 12, 21],
    [3, 13, 17],
    [4, 11, 19],
    [5, 10, 23],
    [6, 15, 22],
    [7, 14, 18],
  ];
  var myAyy = pArr[iIdx];
  var iSize = myAyy.length;
  var vIdx;
  var iPos;
  var myPointArr = [];

  for (var i = 0; i < iSize; i++) {
    vIdx = myAyy[i];
    iPos = vIdx * 3;
    if (null != x) {
      hGeometry.attributes.position.array[iPos] += x;
    }
    if (null != y) {
      hGeometry.attributes.position.array[iPos + 1] += y;
    }
    if (null != z) {
      hGeometry.attributes.position.array[iPos + 2] += z;
    }
  }
}

export default {
  scene,
  camera,
  renderer,
  gridHelper,
  setDrager,
  initScene,
  render,
  drawCube,
  regHover,
  regDrop,
  setCamPosi,
  regClick,
  getCurSelectedMess,
  resetScene,
};
